/*
 *
 * Copyright (c) 2007, Sun Microsystems, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of Sun Microsystems nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package app_files.bluetooth.server;

import app_files.bluetooth.server.BTImageServer;
import app_files.MediaNet;
import java.io.IOException;

import java.util.Vector;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Ticker;
import app_files.files.File;


/**
 * Allows the use to customize the items to be published,
 * creates the corresponding service record to describe this list
 * and send the items to clients by request.
 *
 * @version ,
 */
final public class ConfigureServer implements CommandListener {
    /** Keeps the help message. */
    private final String helpText =
        "The server is started by default.\n\n" +
        "All items are published initially. Change this by corresponding" +
        " commands - the changes have an effect immediately.\n\n" +
        "If an item is removed from the published list, it can't " + "be downloaded.";

    /** This command goes to the main screen. */
    private final Command backCommand = new Command("Back", Command.BACK, 2);

    /** Adds the selected item to the published list. */
    private final Command addCommand = new Command("Publish", Command.SCREEN, 1);

    /** Removes the selected item from the published list. */
    private final Command removeCommand = new Command("Remove", Command.SCREEN, 1);

    /** Shows the help message. */
    private final Command helpCommand = new Command("Help", Command.HELP, 1);

    /** The list control to configure items to share. */
    private final List list = new List("Configure Server", List.IMPLICIT);

    /** The help screen for the server. */
    private final Alert helpScreen = new Alert("Help");

    /** Keeps the parent MIDlet reference to process specific actions. */
    private MediaNet parent;

    /** The list of file names. */
    private Vector names;

    /** These images are used to indicate the picture is published. */
    private Image onImage;

    /** These images are used to indicate the picture is published. */
    private Image offImage;
    
    private String showing_type;

    /** Keeps an information about what items are published. */
    private boolean[] published;

    /** This object handles the real transmission. */
    private BTImageServer bt_server;

    /** Constructs server GUI. */
    public ConfigureServer(MediaNet parent) {
        this.parent = parent;
        //bt_server = new BTImageServer(this);
        setupIdicatorImage();
        setupList();
        //published = new boolean[list.size()];

        // prepare main screen
        list.addCommand(backCommand);
        list.addCommand(addCommand);
        list.addCommand(removeCommand);
        list.addCommand(helpCommand);
        list.setCommandListener(this);

        // prepare help screen
        helpScreen.addCommand(backCommand);
        helpScreen.setTimeout(Alert.FOREVER);
        helpScreen.setString(helpText);
        helpScreen.setCommandListener(this);
        
       Ticker t = new Ticker("Choose items you want to publish...");
       list.setTicker(t);
       Display.getDisplay(parent).setCurrent(list);

    }

    /**
     * Process the command event.
     *
     * @param c - the issued command.
     * @param d - the screen object the command was issued for.
     */
    public void commandAction(Command c, Displayable d) {
        if ((c == backCommand) && (d == list)) {
            destroy();
            parent.show();

            return;
        }

        if ((c == backCommand) && (d == helpScreen)) {
            Display.getDisplay(parent).setCurrent(list);

            return;
        }

        if (c == helpCommand) {
            Display.getDisplay(parent).setCurrent(helpScreen);

            return;
        }

        /*
         * Changing the state of base of published items
         */
        int index = list.getSelectedIndex();

        // nothing to do
        if ((c == addCommand) == published[index]) {
            return;
        }

        // update information and view
        published[index] = c == addCommand;

        Image stateImg = (c == addCommand) ? onImage : offImage;
        list.set(index, list.getString(index), stateImg);
        
        int attr_id = app_files.MediaNet.stringToAttrID(showing_type);
        
        // update bluetooth service information
        if (!bt_server.changeInfo(list.getString(index), attr_id, published[index])) {
            // either a bad record or SDDB is busy
            Alert al = new Alert("Error", "Can't update base", null, AlertType.ERROR);
            al.setTimeout(MediaNet.ALERT_TIMEOUT);
            Display.getDisplay(parent).setCurrent(al, list);

            // restore internal information
            published[index] = !published[index];
            stateImg = published[index] ? onImage : offImage;
            list.set(index, list.getString(index), stateImg);
        }
    }

    /**
     * We have to provide this method due to "do not do network
     * operation in command listener method" restriction, which
     * is caused by crooked midp design.
     *
     * This method is called by BTImageServer after it is done
     * with bluetooth initialization and next screen is ready
     * to appear.
     */
    void completeInitialization(boolean isBTReady) {
        // bluetooth was initialized successfully.
        if (isBTReady) {
            Ticker t = new Ticker("Choose items you want to publish...");
            list.setTicker(t);
            Display.getDisplay(parent).setCurrent(list);

            return;
        }

        // something wrong
        Alert al = new Alert("Error", "Can't initialize bluetooth", null, AlertType.ERROR);
        al.setTimeout(MediaNet.ALERT_TIMEOUT);
        Display.getDisplay(parent).setCurrent(al, parent.getDisplayable());
    }

    /** Destroys this component. */
    public void destroy() {
        // finalize the server work
        //bt_server.destroy();
    }

    /**
     * Creates the image to indicate the base state.
     */
    private void setupIdicatorImage() {
        // create "on" image
        try {
            onImage = Image.createImage("/images/st-on.png");
        } catch (IOException e) {
            // provide off-screen image then
            onImage = createIndicatorImage(12, 12, 0, 255, 0);
        }

        // create "off" image
        try {
            offImage = Image.createImage("/images/st-off.png");
        } catch (IOException e) {
            // provide off-screen image then
            offImage = createIndicatorImage(12, 12, 255, 0, 0);
        }
    }

    /**
     * Reads in a list of files from the xml file useing the ReadFile class.
     */
    private void setupList() {
        names = new Vector();
        list.setCommandListener(this);
        
        Vector files = app_files.xml.ReadFile.getFileDetails("All");
        for (int n = 0; n < files.size(); n++){
            File file = (File) files.elementAt(n);
            names.addElement((String) file.getLocation());
            list.append((String) file.getName(), onImage);
            //published[n] = true;
        }
    }

    /**
     * Creates the off-screen image with specified size an color.
     */
    private Image createIndicatorImage(int w, int h, int r, int g, int b) {
        Image res = Image.createImage(w, h);
        Graphics gc = res.getGraphics();
        gc.setColor(r, g, b);
        gc.fillRect(0, 0, w, h);

        return res;
    }
} // end of class 'ConfigureServer' definition
